/*
 * @Author: Jimmy
 * @LastModifiedBy: Jimmy
 * @Date: 2024-07-06 20:57:49
 * @LastEditTime: 2024-07-07 15:04:17
 * @FilePath: /nest_study/server/src/modules/system/dict/dict.service.ts
 */
import { Injectable } from '@nestjs/common';
import { CreateDictDataDto, CreateDictTypeDto, ListDictData, ListDictType, UpdateDictDataDto, UpdateDictTypeDto } from './dto/index.dto';
import { ExportTable } from 'src/common/utils/export';
import { Response } from 'express';
import { InjectRepository } from '@nestjs/typeorm';
import { SystemDictTypeEntity } from './entities/dict.type.entity';
import { SystemDictDataEntity } from './entities/dict.data.entity';
import { Repository } from 'typeorm';
import { ResultData } from 'src/common/utils/result';

@Injectable()
export class DictService {
  constructor(
    @InjectRepository(SystemDictTypeEntity)
    private readonly dictType: Repository<SystemDictTypeEntity>,
    @InjectRepository(SystemDictDataEntity)
    private readonly dictData: Repository<SystemDictDataEntity>
  ) { }
  //字典类型
  //新增
  async createType(info: CreateDictTypeDto) {
    let { code, name } = info;
    if (!name || !code) {
      return ResultData.fail(500, '字典名称、编码不能为空')
    }
    let entity = this.dictType.createQueryBuilder('dict_type');
    let count = await entity.where("dict_type.code = :code OR dict_type.name = :name", { code, name }).getCount();
    if (count > 0) {
      return ResultData.fail(500, '字典名称或编码已存在')
    }
    await this.dictType.save(info);
    return ResultData.ok()
  }
  //更新
  async updateType(info: UpdateDictTypeDto) {
    try {
      let { id, name } = info;
      if (!id) {
        return ResultData.fail(500, '参数缺失')
      }
      let result = await this.dictType.findOne({
        where: { name }
      });
      if (result && result?.id != id) {
        return ResultData.fail(500, '字典名称已存在')
      }
      let data = await this.dictType.findOne({
        where: { id }
      });
      if (!data) {
        return ResultData.fail(500, '更新信息不存在');
      }
      let res = await this.dictType.update({ id }, info);
      if (res.affected) {
        return ResultData.ok('更新成功');
      } else {
        return ResultData.fail(500, '更新失败')
      }
    } catch (err) {
      return ResultData.fail(500, '更新失败' + err)
    }
  }
  //移除
  async removeType(info: { ids: number[] }) {
    let { ids } = info;
    if (!ids || ids.length === 0) {
      return ResultData.fail(500, '参数错误');
    }
    await this.dictType.delete(ids);
    let entity = this.dictData.createQueryBuilder('dict_data').where('dict_data.parent IN (:...ids)', { ids });
    let count = await entity.getCount();
    if (count > 0) {
      await entity.delete().execute();
    }
    return ResultData.ok();
  }
  //查询
  async queryTypeList(query: ListDictType) {
    let { name, code, status } = query;
    let entity = this.dictType.createQueryBuilder('dict_type');
    if (name) {
      entity.andWhere(`dict_type.name LIKE "%${name}%"`);
    }
    if (code) {
      entity.andWhere(`dict_type.code = :code`, { code });
    }
    if (status) {
      entity.andWhere(`dict_type.status = :status`, { status });
    }
    entity.skip(query.size * (query.page - 1)).take(query.size);
    const [list, total] = await entity.getManyAndCount();
    return ResultData.ok({
      list,
      total,
      size: query.size,
      page: query.page
    })
  }

  //字典数据
  //新增
  async createData(info: CreateDictDataDto) {
    let { parent, label, value } = info;
    if (!parent) {
      return ResultData.fail(500, '父级字典编码不能为空')
    }
    if (!label || !value) {
      return ResultData.fail(500, '字典标签、值不能为空')
    }
    let result = await this.dictData.findOne({
      where: { parent, label }
    })
    console.log(result);
    if (result) {
      return ResultData.fail(500, '字典标签已存在')
    }
    let data = await this.dictData.findOne({
      where: { parent, value }
    })
    if (data) {
      return ResultData.fail(500, '字典值已存在')
    }
    await this.dictData.save(info);
    return ResultData.ok();
  }
  //新增
  async updateData(info: UpdateDictDataDto) {
    try {
      let { id, label, value, parent } = info;
      if (!id) {
        return ResultData.fail(500, '参数缺失')
      }
      let result = await this.dictData.findOne({
        where: { label, parent }
      });
      if (result && result?.id != id) {
        return ResultData.fail(500, '字典标签已存在')
      }
      let data = await this.dictData.findOne({
        where: { value, parent }
      });
      if (data && data?.id != id) {
        return ResultData.fail(500, '字典值已存在');
      }
      let resultData = await this.dictData.findOne({
        where: { id }
      });
      if (!resultData) {
        return ResultData.fail(500, '更新信息不存在');
      }
      let res = await this.dictData.update({ id }, info);
      if (res.affected) {
        return ResultData.ok('更新成功');
      } else {
        return ResultData.fail(500, '更新失败')
      }
    } catch (err) {
      return ResultData.fail(500, '更新失败' + err)
    }
  }
  //移除
  async removeData(info: { ids: number[] }) {
    let { ids } = info;
    if (!ids || ids.length === 0) {
      return ResultData.fail(500, '参数错误');
    }
    await this.dictData.delete(ids);
    return ResultData.ok();
  }
  //查询
  async queryDataList(query: ListDictData) {
    let { parent, label, status } = query;
    let entity = this.dictData.createQueryBuilder('dict_data');
    if (parent) {
      entity.andWhere(`dict_data.parent= :parent`, { parent });
    }
    if (label) {
      entity.andWhere(`dict_data.label LIKE "%${label}%"`);
    }
    if (status) {
      entity.andWhere(`dict_data.status = :status`, { status });
    }
    entity.skip(query.size * (query.page - 1)).take(query.size);
    const [list, total] = await entity.getManyAndCount();
    return ResultData.ok({
      list,
      total,
      size: query.size,
      page: query.page
    })
  }

  // 根据字典类型查询所有字典数据
  async queryDataAll(query: { code: string, status?: number; }) {
    let { code, status } = query;
    if (!code) {
      return ResultData.fail(500, '缺少字典类型')
    }
    let entity = this.dictData.createQueryBuilder('dict_data');
    if (status) {
      entity.where('dict_data.status = :status', { status });
    }
    entity.where('dict_data.parent = :code', { code });
    const [list, total] = await entity.getManyAndCount();
    return ResultData.ok({
      list,
      total
    })
  }

  //导出文件
  async export(res: Response, body: ListDictType) {
    delete body.page;
    delete body.size;
    const list = await this.dictType.createQueryBuilder().where(body).getMany();
    const options = {
      sheetName: '字典数据',
      data: list,
      header: [
        { title: '字典主键', dataIndex: 'id' },
        { title: '字典名称', dataIndex: 'name' },
        { title: '字典编码', dataIndex: 'code' },
        { title: '状态', dataIndex: 'status' },
      ]
    }
    ExportTable(options, res);
  }
}
